import { useUserStore } from '@/stores/users.js'

/**
 * 防抖函数
 * @param {*} fn
 * @param {*} wait 防抖间隔
 * @param {*} immediate 立即执行
 * @returns
 */
function debounce(fn, wait = 300, immediate = true) {
    let t = null
    let canChangeImmdiate = !!immediate
    if (typeof fn !== "function") {
        throw new TypeError("debounce 第一个参数必须是函数")
    }

    return function debounceFn(...args) {
        t && clearTimeout(t)
        if (immediate) {
            if (!t) {
                fn.apply(this, args)
                immediate = false
            }
        } else {
            t = setTimeout(() => {
                fn.apply(this, args)
                if (canChangeImmdiate) {
                    immediate = true
                    t = null
                }
            }, wait)
        }
    }
}



function hasPermission(value,el=false){
	//判断传入的数据是否符合自己设定的预期
	if(!Array.isArray(value)){
		//如果传入的不是数组则抛出错误
		throw new Error(`需要传入正确的数据类型`)
	}
	//判断是否拥有权限
    const userStore = useUserStore();
	let data = userStore.permissionCode  //存储着是否拥有该请求权限的数组
	//如果在data中包含了传入的数据字段，则代表拥有权限，没有则返回 -1  此时如果为false 则代表没有权限
	let hasAuth = value.findIndex(v=>data.includes(v))!=-1
	//当使用的自定义指令dom存在时，且没有权限
	if(el && !hasAuth){
		//移除组件
		el.parentNode.removeChild(el)
	}
}


export default {
    install(app){
        // app 为根组件实例
        app.directive('permission',{
            mounted(el,binding) {
                hasPermission(binding.value,el)
            },
        })


        //只需要在组件或者dom元素上对需要防抖或者节流的事件添加以下指令即可
        app.directive("debounce", {
            update(el, bind, vnode) {
                // 默认给click事件添加防抖
                const { value: fn, arg = "click", modifiers } = bind
                const { immediate = false } = modifiers
                const modNumKeys = Object.keys(modifiers).filter((key) => !isNaN(+key))
                const wait = modNumKeys.length > 0 ? modNumKeys[0] : 300
                if (vnode.componentInstance) {
                    // 组件
                    for (const [evtName, handlers] of Object.entries(vnode.componentInstance._events)) {
                        if (arg == evtName) {
                            vnode.componentInstance._events[evtName] = handlers.map((handler) =>
                                debounce(handler, wait, immediate)
                            )
                        }
                    }
                } else {
                    // dom元素
                    for (const [evtName, handler] of Object.entries(vnode.data.on)) {
                        if (evtName == arg) {
                            if (Array.isArray(vnode.data.on[arg].fns)) {
                                vnode.data.on[arg].fns = vnode.data.on[arg].fns.map((fn) =>
                                    debounce(fn, wait, immediate)
                                )
                            } else {
                                vnode.data.on[arg].fns = debounce(vnode.data.on[arg].fns, wait, immediate)
                            }
                        }
                    }
                }
            }
        })
    }
}

